#include "gdevice.h"

/**
 * 根据key值查找设备节点
 * 
 * 功能：在设备链表中根据指定的key值查找对应的设备节点
 * 
 * @param pdev 设备链表的头指针
 * @param key  要查找的设备key值（通常来自通信协议中的设备标识）
 * @return     找到的设备节点指针，未找到返回NULL
 * 
 * 查找逻辑：
 * 1. 检查链表是否为空
 * 2. 遍历链表比较每个节点的key值
 * 3. 找到匹配节点立即返回，否则遍历完返回NULL
 */
struct gdevice *find_gdevice_by_key(struct gdevice *pdev, unsigned char key)
{
    struct gdevice *p = NULL;//用于遍历链表的临时指针

    //检查输入参数有效性
    if (NULL == pdev){
        return NULL;//链表为空，直接返回NULL
    } 
    p = pdev;//从链表头开始遍历

    while (NULL != p)//遍历设备链表
    {
        //比较当前节点的key值是否与目标key值匹配
        if(p->key == key){
            return p;//找到匹配任务，返回设备节点指针
        } 
        p = p->next;//移动到下一个设备节点
    } 

    return NULL;//遍历完 整个链表都未找到匹配设备，返回NULL
} 


/**
 * 设置GPIO引脚状态
 * 
 * 功能：根据设备节点中的配置信息设置对应GPIO引脚的模式和状态
 * 
 * @param pdev 指向设备节点的指针
 * @return     成功返回0，失败返回-1
 * 
 * 设置流程：
 * 1. 检查设备节点有效性
 * 2. 检查GPIO引脚是否有效(-1表示无效)
 * 3. 设置GPIO模式(INPUT/OUTPUT)
 * 4. 设置GPIO电平状态(LOW/HIGH)
 */
int set_gpio_gdevice_status(struct gdevice *pdev)
{
    if (NULL == pdev){//检查输入参数有效性
        return -1;//设备节点为空，返回错误
    } 

    //检查GPIO引脚是否有效（-1表示无效引脚）
    if (-1 != pdev->gpio_pin)
    {
        //检查并设置GPIO模式（INPUT/OUTPUT/-1）
        if (-1 != pdev->gpio_mode){
            //设置引脚为输入或输出模式
            pinMode(pdev->gpio_pin, pdev->gpio_mode);
        } 

        //检查并设置GPIO电平状态（LOW/HIGH/-1）
        if (-1 != pdev->gpio_status){
            //设置引脚高低电平状态
            digitalWrite(pdev->gpio_pin, pdev->gpio_status);
        }
    } 

    return 0;//成功设置GPIO状态，返回0
} 

/**
 * 使用头插法将设备添加到设备链表中
 * 
 * 功能：将新的设备节点插入到设备链表的头部
 * 
 * @param phead  设备链表的头指针
 * @param device 要添加的设备节点指针
 * @return       更新后的链表头指针
 * 
 * 插入方式：头插法
 * - 如果链表为空，直接将新设备作为头节点
 * - 如果链表不为空，将新设备插入到链表头部成为新的头节点
 * 时间复杂度：O(1)
 */
struct gdevice *add_device_to_gdevice_list(struct gdevice *phead, struct gdevice *device)
{
    struct gdevice *pgdevice;  // 临时指针变量

    // 检查链表是否为空
    if(NULL == phead){
        // 链表为空，将新设备作为链表的第一个节点
        pgdevice = device;
        return pgdevice;
    }else{
        // 链表不为空，使用头插法将新设备插入到链表头部
        device->next = phead;  // 新设备节点指向原来的头节点
        phead = device;        // 更新头指针为新设备节点
        return phead;
    }
}